﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Rappelz.GameServer.Network.GameClient
{
    /// <summary>
    /// Enum for packets the server can send to the game client
    /// </summary>
    public enum ClientOutPackets : ushort
    {
        MsgResult = 0,
        TimeSync = 2,
        Enter = 3,
        LoginResult = 4,
        MoveAck = 6,
        Move = 8,
        Leave = 9,
        SetTime = 10,
        RegionAck = 11,
        Warp = 12,
        ChatLocal = 21,
        Chat = 22,
        ChatResult = 24,
        NameChange = 30,
        AttackEvent = 101,
        CantAttack = 102,
        DisconnectDesc = 28,
        WearMessage = 202,
        Inventory = 207,
        ItemDestroyResult = 209,
        TakeItemResult = 210,
        OpenStorage = 211,
        GetChaos = 213,
        BeltSlotInfo = 216,
        ItemCoolTime = 217,
        NpcTradeInfo = 240,
        MarketInfo = 250,
        ItemDestroy = 254,
        ItemCount = 255,
        MixResult = 257,
        ShowSoulstoneCraftWindow = 259,
        ShowSoulstoneRepairWindow = 261,
        ItemDrop = 282,
        UseItemResult = 283,
        SkillCardInfo = 286,
        ItemWearInfoMessage = 287,
        AddSummon = 301,
        EquipSummon = 303,
        Unsummon = 305,
        UnsummonNotice = 306,
        SummonEvolution = 307,
        TamingInfo = 310,
        AddPetInfo = 351,
        ShowPetSetName = 353,
        Skill = 401,
        SkillList = 403,
        StateResult = 406,
        StatusChange = 500,
        State = 505,
        Property = 507,
        HPMPRegen = 516,
        QuestList = 600,
        QuestStatus = 601,
        ShowCreateGuild = 650,
        ChangeLocation = 901,
        WeatherInfo = 902,
        GoldChaosUpdateMessage = 1001,
        LevelMessage = 1002,
        ExpMessage = 1003,
        BonusExpMessage = 1004,
        GameTime = 1101,
        Emotion = 1201,
        CharacterListResult = 2004,
        DialogMessage = 3000,
        UrlList = 9001,
        SecurityNo = 9004,
        AccountResult = 10010,
        ServerListResult = 10022,
        ServerSelectResult = 10024,

        Packet9999 = 9999,
    }

    public class ItemInfoBaseSC
    {
        public uint handle;                         // 0x0
        public int Code;                            // 0x4
        public long uid;                            // 0x8
        public long count;                          // 0x10
        public uint endurance;                      // 0x18
        public int dura;
        public byte enhance;                        // 0x1C
        public byte level;                          // 0x1D
        public uint flag;                            // 0x1E
        public int[] socket = new int[4];           // 0x22
        public int remain_time;                     // 0x32
        public byte elemental_effect_type;          // 0x36
        public int elemental_effect_remain_time;    // 0x37
        public int elemental_effect_attack_point;   // 0x3B
        public int elemental_effect_magic_point;    // 0x3F
    }

    public class ItemInfoSC : ItemInfoBaseSC
    {
        public short wear_position;                 // 0x43
        public uint own_summon_handle;              // 0x45
        public int index;                           // 0x49

        public void WriteToPacket(PacketOut packet)
        {
            packet.WriteUInt32(handle);
            packet.WriteInt32(Code);
            packet.WriteInt64(uid);
            packet.WriteInt64(count);
            packet.WriteInt32(dura);
            packet.WriteUInt32(endurance);
            packet.WriteByte(enhance);
            packet.WriteByte(level);
            packet.WriteUInt32(flag);
            packet.WriteInt32(socket[0]);
            packet.WriteInt32(socket[1]);
            packet.WriteInt32(socket[2]);
            packet.WriteInt32(socket[3]);
            packet.WriteInt32(remain_time);
            packet.WriteByte(elemental_effect_type);
            packet.WriteInt32(elemental_effect_remain_time);
            packet.WriteInt32(elemental_effect_attack_point);
            packet.WriteInt32(elemental_effect_magic_point);
            packet.WriteInt32(0); // appearance_code

            packet.WriteInt16(wear_position);

            packet.WriteUInt32(own_summon_handle);

            packet.WriteInt32(index);
        }
    }

    public class ItemInfoPacketSC : PacketOut
    {

        public String szName;
        public byte race;

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="buf">Buffer containing packet data to read from</param>
        /// <param name="start">Starting index into buf</param>
        /// <param name="size">Number of bytes to read from buf</param>
        public ItemInfoPacketSC()
            : base((ushort)0)
        {
//            szName = ReadString(19);
//            race = (byte)ReadByte();
        }
    }

    public class c_encint
    {
        public class HiLo
        {
            public short h;
            public short l;
        }

        public c_encint(int n)
        {
            short r1 = 0;// (short)Globals.GetRandomInt32();
            short r2 = 0;// (short)Globals.GetRandomInt32();

            m_L.h = r2;
            m_H.h = r1;
            m_H.l = (short)(Marshal.HiWord(n) + (2 * (r2-r1)));
            m_L.l = (short)(Marshal.LoWord(n) - (2 * (r2 + r1)));
        }

        // UserDefinedType: c_encint<int,short,c_enc_rand_gen>
        // Function       :   public void c_encint<int,short,c_enc_rand_gen>(const class c_encint<int,short,c_enc_rand_gen> &)
        // Function       :   public void c_encint<int,short,c_enc_rand_gen>()
        // Function       :   public class c_encint<int,short,c_enc_rand_gen> & operator=(const class c_encint<int,short,c_enc_rand_gen> &)
        // Function       :   public int operator int()
        // Function       :   public int value()
        // Function       :   public short hash_id()
        // Function       :   public class c_encint<int,short,c_enc_rand_gen> & set_new_value(const class c_encint<int,short,c_enc_rand_gen> &)
        // Function       :   public bool prior(const class c_encint<int,short,c_enc_rand_gen> &)
        // Function       :   public class c_encint<int,short,c_enc_rand_gen> operator+(const class c_encint<int,short,c_enc_rand_gen> &)
        // Function       :   public class c_encint<int,short,c_enc_rand_gen> operator+()
        // Function       :   public class c_encint<int,short,c_enc_rand_gen> operator-(const class c_encint<int,short,c_enc_rand_gen> &)
        // Function       :   public class c_encint<int,short,c_enc_rand_gen> operator-()
        // Function       :   public class c_encint<int,short,c_enc_rand_gen> operator++(int)
        // Function       :   public class c_encint<int,short,c_enc_rand_gen> & operator++()
        // Function       :   public class c_encint<int,short,c_enc_rand_gen> operator--(int)
        // Function       :   public class c_encint<int,short,c_enc_rand_gen> & operator--()
        // Function       :   public bool operator==(const class c_encint<int,short,c_enc_rand_gen> &)
        // Function       :   public bool operator!=(const class c_encint<int,short,c_enc_rand_gen> &)
        // Function       :   public bool operator<(const class c_encint<int,short,c_enc_rand_gen> &)
        // Function       :   public bool operator>(const class c_encint<int,short,c_enc_rand_gen> &)
        // Function       :   public bool operator<=(const class c_encint<int,short,c_enc_rand_gen> &)
        // Function       :   public bool operator>=(const class c_encint<int,short,c_enc_rand_gen> &)
        // Function       :   public class c_encint<int,short,c_enc_rand_gen> & operator+=(const class c_encint<int,short,c_enc_rand_gen> &)
        // Function       :   public class c_encint<int,short,c_enc_rand_gen> & operator-=(const class c_encint<int,short,c_enc_rand_gen> &)
        // Function       :   public class c_encint<int,short,c_enc_rand_gen> & operator*=(const class c_encint<int,short,c_enc_rand_gen> &)
        // Function       :   public class c_encint<int,short,c_enc_rand_gen> & operator/=(const class c_encint<int,short,c_enc_rand_gen> &)
        // Function       :   public class c_encint<int,short,c_enc_rand_gen> & operator%=(const class c_encint<int,short,c_enc_rand_gen> &)
        // Function       :   public class c_encint<int,short,c_enc_rand_gen> operator*(const class c_encint<int,short,c_enc_rand_gen> &)
        // Function       :   public class c_encint<int,short,c_enc_rand_gen> operator/(const class c_encint<int,short,c_enc_rand_gen> &)
        // Function       :   public class c_encint<int,short,c_enc_rand_gen> operator%(const class c_encint<int,short,c_enc_rand_gen> &)
        // Function       :   private short sum()
        // Function       :   private short sub()
        // Function       :   private void enc(int)
        // Function       :   private int dec()

        public HiLo m_H = new HiLo();
        public HiLo m_L = new HiLo();

        public void WriteToPacket(PacketOut packet)
        {
            packet.WriteInt16(m_H.h);
            packet.WriteInt16(m_H.l);
            packet.WriteInt16(m_L.h);
            packet.WriteInt16(m_L.l);
        }


    }


    public class EnterPacketSC
    {
        public enum MainType : int
        {
            Player = 0,
            NPC = 1,
            StaticObject = 2,
        }

        public enum SubType : int
        {
            Player = 0,
            NPC = 1,
            Item = 2,
            Mob = 3,
            Summon = 4,
            SkillProp = 5,
            FieldProp = 6,
            Pet = 7,
        }

        public class ItemPickupOrder
        {
            public uint drop_time;
            public uint[] hPlayer = new uint[3];
            public int[] nPartyID = new int[3];
        }

        public class ItemInfo
        {
            public c_encint code;// Data           :     this+0x0, Member, Type: class c_encint<int,short,c_enc_rand_gen>, 
            public long cnt;
            public ItemPickupOrder pick_up_order = new ItemPickupOrder();

            public void WriteToPacket(PacketOut packet)
            {
                code.WriteToPacket(packet);
                packet.WriteInt64(cnt);
                packet.WriteUInt32(pick_up_order.drop_time);
                packet.WriteUInt32(pick_up_order.hPlayer[0]);
                packet.WriteUInt32(pick_up_order.hPlayer[1]);
                packet.WriteUInt32(pick_up_order.hPlayer[2]);
                packet.WriteInt32(pick_up_order.nPartyID[0]);
                packet.WriteInt32(pick_up_order.nPartyID[1]);
                packet.WriteInt32(pick_up_order.nPartyID[2]);
            }
        }

        public class SkillInfo
        {
            public uint caster;
            public uint start_time;
            public int skill_num;

            public void WriteToPacket(PacketOut packet)
            {
                packet.WriteUInt32(caster);
                packet.WriteUInt32(start_time);
                packet.WriteInt32(skill_num);
            }
        }

        public class FieldPropInfo
        {
            public int prop_id;
            public float fZOffset;
            public float fRotateX;
            public float fRotateY;
            public float fRotateZ;
            public float fScaleX;
            public float fScaleY;
            public float fScaleZ;
            public bool bLockHeight;
            public float fLockHeight;

            public void WriteToPacket(PacketOut packet)
            {
                packet.WriteInt32(prop_id);
                packet.WriteFloat(fZOffset);
                packet.WriteFloat(fRotateX);
                packet.WriteFloat(fRotateY);
                packet.WriteFloat(fRotateZ);
                packet.WriteFloat(fScaleX);
                packet.WriteFloat(fScaleY);
                packet.WriteFloat(fScaleZ);
                packet.WriteBool(bLockHeight);
                packet.WriteFloat(fLockHeight);
            }
        }

        public class CreatureInfo
        {
            public uint status;
            public float face_direction;
            public int hp;
            public int max_hp;
            public float mp;
            public int max_mp;
            public int level;
            public byte race;
            public uint skin_color;
            public bool is_first_enter;
            public int energy;

            public void WritePacket(PacketOut packet)
            {
                packet.WriteUInt32(status);
                packet.WriteFloat(face_direction);
                packet.WriteInt32(hp);
                packet.WriteInt32(max_hp);
                packet.WriteInt32((int)mp);
                packet.WriteInt32(max_mp);
                packet.WriteInt32(level);
                packet.WriteByte(race);
                packet.WriteUInt32(skin_color);
                packet.WriteBool(is_first_enter);
                packet.WriteInt32(energy);
            }
        }

        public class MonsterInfo : CreatureInfo
        {
            public c_encint monster_id; // Data           :     this+0x26, Member, Type: class c_encint<int,short,c_enc_rand_gen>, 
            // 
            public bool is_tamed;

            public void WriteToPacket(PacketOut packet)
            {
                WritePacket(packet);
                monster_id.WriteToPacket(packet);
                packet.WriteBool(is_tamed);
            }
        }

        public class SummonInfo : CreatureInfo
        {
            public uint master_handle;
            public c_encint summon_code;// Data           :     this+0x2A, Member, Type: class c_encint<int,short,c_enc_rand_gen>, 
            public string szName;       // 0x32, char[0x13]
            public uint skinNum;

            public void WriteToPacket(PacketOut packet)
            {
                WritePacket(packet);
                packet.WriteUInt32(master_handle);
                summon_code.WriteToPacket(packet);
                packet.FillString(szName, 19);
                packet.WriteUInt32(skinNum);
            }
        }

        public class NPCInfo : CreatureInfo
        {
            public c_encint npc_id;// Data           :     this+0x26, Member, Type: class c_encint<int,short,c_enc_rand_gen>, 

            public void WriteToPacket(PacketOut packet)
            {
                WritePacket(packet);
                npc_id.WriteToPacket(packet);
            }
        }

        public class PlayerInfo : CreatureInfo
        {
            public byte sex;// Data           :     this+0x26, Member, Type: unsigned char, 
            public int faceId;// Data           :     this+0x27, Member, Type: int, 
            public int hairId;// Data           :     this+0x2B, Member, Type: int, 
            public string szName;// Data           :     this+0x2F, Member, Type: char[0x13], 
            public ushort job_id;// Data           :     this+0x42, Member, Type: unsigned short, 
            public uint ride_handle;// Data           :     this+0x44, Member, Type: unsigned int, 
            public int guild_id;// Data           :     this+0x48, Member, Type: int, 
            public int hair_cut;// Data           :     this+0x48, Member, Type: int, 
            public int hair_dye;// Data           :     this+0x48, Member, Type: int, 
            public int unk1;// Data           :     this+0x48, Member, Type: int, 
            public int face;// Data           :     this+0x48, Member, Type: int, 


            public void WriteToPacket(PacketOut packet)
            {
                WritePacket(packet);
                packet.WriteByte(sex);
                packet.WriteInt32(faceId);
                packet.WriteInt32(face);
                packet.WriteInt32(hairId);
                packet.WriteInt32(hair_cut);
                packet.WriteInt32(unk1);
                packet.WriteInt32(hair_dye);

                packet.FillString(szName, 19);
                packet.WriteUInt16(job_id);
                packet.WriteUInt32(ride_handle);
                packet.WriteInt32(guild_id);
            }
        }

        public class PetInfo : CreatureInfo
        {
            public uint master_handle;// Data           :     this+0x26, Member, Type: unsigned int, 
            public c_encint pet_code;// Data           :     this+0x2A, Member, Type: class c_encint<int,short,c_enc_rand_gen>, 
            public string szName;// Data           :     this+0x32, Member, Type: char[0x13], 

            public void WriteToPacket(PacketOut packet)
            {
                WritePacket(packet);
                packet.WriteUInt32(master_handle);
                pet_code.WriteToPacket(packet);
                packet.FillString(szName, 19);
            }
        }

        public byte type; // 7
        public uint handle; // 8
        public float x; // 12
        public float y; // 16
        public float z; // 20
        public byte layer; // 24
        public byte ObjType; // 25

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="buf">Buffer containing packet data to read from</param>
        /// <param name="start">Starting index into buf</param>
        /// <param name="size">Number of bytes to read from buf</param>
        public EnterPacketSC()
        {
//            szName = ReadString(19);
//            race = (byte)ReadByte();
        }

        public void WriteToPacket(PacketOut packet)
        {
            packet.WriteByte(type);
            packet.WriteUInt32(handle);
            packet.WriteFloat(x);
            packet.WriteFloat(y);
            packet.WriteFloat(z);
            packet.WriteByte(layer);
            packet.WriteByte(ObjType);

        }


    }

    public class AttackEventPacketSC
    {
        public enum Flag : int
        {
            PerfectBlock = 1,
            Block = 2,
            Miss = 4,
            Critical = 8,
        }

        public enum AttackAction : int
        {
            End = 1,
            Aiming = 2,
            Attack = 3,
            Cancel = 4,
        }

        public enum AttackFlag : int
        {
            Bow = 1,
            CrossBow = 2,
            DoubleWeapon = 4,
            DoubleAttack = 8,
        }

        public class AttackInfo
        {
            public int damage;// Data           :     this+0x0, Member, Type: short, damage
            public int mp_damage;// Data           :     this+0x2, Member, Type: short, 
            public byte flag;// Data           :     this+0x4, Member, Type: unsigned char, flag
            public uint[] elemental_damage = new uint[7];// Data           :     this+0x5, Member, Type: unsigned short[0x7], 
            public uint target_hp;// Data           :     this+0x13, Member, Type: unsigned int, 
            public uint target_mp;// Data           :     this+0x17, Member, Type: unsigned short, 
            public int attacker_damage;// Data           :     this+0x19, Member, Type: short, 
            public int attacker_mp_damage;// Data           :     this+0x1B, Member, Type: short, 
            public uint attacker_hp;// Data           :     this+0x1D, Member, Type: unsigned int, 
            public uint attacker_mp;// Data           :     this+0x21, Member, Type: unsigned short, 

            public void WriteToPacket(PacketOut packet)
            {
                packet.WriteInt32(damage);
                packet.WriteInt32(mp_damage);
                packet.WriteByte(flag);
                for (int i = 0; i < 7; ++i)
                {
                    packet.WriteUInt32(elemental_damage[i]);
                }
                packet.WriteUInt32(target_hp);
                packet.WriteUInt32(target_mp);

                packet.WriteInt32(attacker_damage);
                packet.WriteInt32(attacker_mp_damage);
                packet.WriteUInt32(attacker_hp);
                packet.WriteUInt32(attacker_mp);
            }
        }

        public uint attacker_handle;    // 0x07
        public uint target_handle;      // 0x0b (11)
        public ushort attack_speed;     // 0x0f (15)
        public ushort attack_delay;     // 0x11 (17)
        public byte attack_action;      // 0x13 (19)
        public byte attack_flag;        // 0x14 (20)
        public byte count;              // 0x15 (21)
        public List<AttackInfo> v_Info = new List<AttackInfo>();

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="buf">Buffer containing packet data to read from</param>
        /// <param name="start">Starting index into buf</param>
        /// <param name="size">Number of bytes to read from buf</param>
        public AttackEventPacketSC()
        {
        }

        public void WriteToPacket(PacketOut packet)
        {
            packet.WriteUInt32(attacker_handle);
            packet.WriteUInt32(target_handle);
            packet.WriteUInt16(attack_speed);
            packet.WriteUInt16(attack_delay);
            packet.WriteByte(attack_action);
            packet.WriteByte(attack_flag);
            packet.WriteByte(count);

            foreach (AttackInfo i in v_Info)
            {
                i.WriteToPacket(packet);
            }

        }


    }

    public class SkillListPacket
    {
        public class SkillInfo
        {
            // UserDefinedType:   SkillInfo
            public int skill_id;// Data           :     this+0x0, Member, Type: int, 
            public byte base_skill_level;// Data           :     this+0x4, Member, Type: unsigned char, 
            public byte current_skill_level;// Data           :     this+0x5, Member, Type: unsigned char, 
            public uint total_cool_time;// Data           :     this+0x6, Member, Type: unsigned long, 
            public uint remain_cool_time;// Data           :     this+0xA, Member, Type: unsigned long, 
        }

        public uint target;// Data           :   this+0x7, Member, Type: unsigned int, 
        public ushort count;// Data           :   this+0xB, Member, Type: unsigned short, 
        public bool reset;// Data           :   this+0xD, Member, Type: bool, reset
        public List<SkillInfo> skills = new List<SkillInfo>();

        public void WriteToPacket(PacketOut packet)
        {
            count = (ushort)skills.Count;
            packet.WriteUInt32(target);
            packet.WriteUInt16(count);
            packet.WriteByte((byte)(reset ? 1 : 0));

            foreach (SkillInfo i in skills)
            {
                packet.WriteInt32(i.skill_id);
                packet.WriteByte(i.base_skill_level);
                packet.WriteByte(i.current_skill_level);
                packet.WriteUInt32(i.total_cool_time);
                packet.WriteUInt32(i.remain_cool_time);
            }
        }


    }

    public class SkillPacket
    {
        public class CancelType
        {
            public uint tm;
            public ushort nErrorCode;
        }
        public class CompleteType
        {
            public uint tm;
            public ushort nErrorCode;
        }
        public class CastType
        {
            public uint tm;
            public ushort nErrorCode;
        }
        public class FireType
        {
            public bool bMultiple;     // 0
            public float range;        // 1
            public byte target_count;  // 5
            public byte fire_count;    // 6
            public ushort count;       // 7
        }
        // UserDefinedType:   FireType
        // Data           :     this+0x0, Member, Type: bool, bMultiple
        // Data           :     this+0x1, Member, Type: float, range
        // Data           :     this+0x5, Member, Type: unsigned char, target_count
        // Data           :     this+0x6, Member, Type: unsigned char, fire_count
        // Data           :     this+0x7, Member, Type: unsigned short, count

        // Enum           :   <unnamed-tag>, Type: int
        // Data           :     constant 0x0, Constant, Type: int, FIRE
        // Data           :     constant 0x1, Constant, Type: int, CASTING
        // Data           :     constant 0x2, Constant, Type: int, CASTING_UPDATE
        // Data           :     constant 0x3, Constant, Type: int, CANCEL
        // Data           :     constant 0x4, Constant, Type: int, REGION_FIRE
        // Data           :     constant 0x5, Constant, Type: int, COMPLETE
        
        public ushort skill_id;// Data           :   this+0x7, Member, Type: unsigned short, skill_id
        public byte skill_level;// Data           :   this+0x9, Member, Type: char, 
        public uint caster;// Data           :   this+0xA, Member, Type: unsigned int, 
        public uint target;// Data           :   this+0xE, Member, Type: unsigned int, 
        public float x;// Data           :   this+0x12, Member, Type: float, x
        public float y;// Data           :   this+0x16, Member, Type: float, y
        public float z;// Data           :   this+0x1A, Member, Type: float, z
        public byte layer;// Data           :   this+0x1E, Member, Type: unsigned char, layer
        public byte type;// Data           :   this+0x1F, Member, Type: char, type
        public short hp_cost;// Data           :   this+0x20, Member, Type: short, hp_cost
        public short mp_cost;// Data           :   this+0x22, Member, Type: short, 
        public int caster_hp;// Data           :   this+0x24, Member, Type: int, 
        public short caster_mp;// Data           :   this+0x28, Member, Type: short, 

        public CastType baseType = new CastType();
        public FireType fireType = new FireType();

// Data           :   this+0x2A, Member, Type: struct TS_SC_SKILL::CancelType, cancel
// UserDefinedType:     TS_SC_SKILL::CancelType
// 
// Data           :   this+0x2A, Member, Type: struct TS_SC_SKILL::CompleteType, complete
// UserDefinedType:     TS_SC_SKILL::CompleteType
// 
// Data           :   this+0x2A, Member, Type: struct TS_SC_SKILL::CastType, cast
// UserDefinedType:     TS_SC_SKILL::CastType
// 
// Data           :   this+0x2A, Member, Type: struct TS_SC_SKILL::FireType, fire
// UserDefinedType:     TS_SC_SKILL::FireType
// 
// UserDefinedType: TS_SC_SKILL::CancelType
// UserDefinedType: TS_SC_SKILL::CompleteType
// UserDefinedType: TS_SC_SKILL::CastType
// Data           :   this+0x0, Member, Type: unsigned long, tm
// Data           :   this+0x4, Member, Type: unsigned short, nErrorCode
// UserDefinedType: TS_SC_SKILL::FireType
// Data           :   this+0x0, Member, Type: bool, bMultiple
// Data           :   this+0x1, Member, Type: float, range
// Data           :   this+0x5, Member, Type: unsigned char, target_count
// Data           :   this+0x6, Member, Type: unsigned char, fire_count
// Data           :   this+0x7, Member, Type: unsigned short, count
// UserDefinedType: TS_SC_SKILL
// BaseClass      :   TS_MESSAGE, offset = 0x0
// Function       :     public void TS_MESSAGE()
// Data           :     this+0x0, Member, Type: unsigned int, size
// Data           :     this+0x4, Member, Type: unsigned short, id
// Data           :     this+0x6, Member, Type: unsigned char, msg_check_sum
// Function       :     public bool TS_MESSAGE::IsValidMessage()
// Function       :     protected unsigned char get_check_sum()
// Function       :     protected void set_check_sum()
// 
// Function       :   public void TS_SC_SKILL::TS_SC_SKILL()
// Data           :   this+0x7, Member, Type: unsigned short, skill_id
// Data           :   this+0x9, Member, Type: char, skill_level
// Data           :   this+0xA, Member, Type: unsigned int, caster
// Data           :   this+0xE, Member, Type: unsigned int, target
// Data           :   this+0x12, Member, Type: float, x
// Data           :   this+0x16, Member, Type: float, y
// Data           :   this+0x1A, Member, Type: float, z
// Data           :   this+0x1E, Member, Type: unsigned char, layer
// Data           :   this+0x1F, Member, Type: char, type
// Data           :   this+0x20, Member, Type: short, hp_cost
// Data           :   this+0x22, Member, Type: short, mp_cost
// Data           :   this+0x24, Member, Type: int, caster_hp
// Data           :   this+0x28, Member, Type: short, caster_mp
// Enum           :   <unnamed-tag>, Type: int
// Data           :     constant 0x0, Constant, Type: int, FIRE
// Data           :     constant 0x1, Constant, Type: int, CASTING
// Data           :     constant 0x2, Constant, Type: int, CASTING_UPDATE
// Data           :     constant 0x3, Constant, Type: int, CANCEL
// Data           :     constant 0x4, Constant, Type: int, REGION_FIRE
// Data           :     constant 0x5, Constant, Type: int, COMPLETE
// UserDefinedType:   CancelType
// UserDefinedType:   CompleteType
// UserDefinedType:   CastType
// Data           :     this+0x0, Member, Type: unsigned long, tm
// Data           :     this+0x4, Member, Type: unsigned short, nErrorCode
// UserDefinedType:   FireType
// Data           :     this+0x0, Member, Type: bool, bMultiple
// Data           :     this+0x1, Member, Type: float, range
// Data           :     this+0x5, Member, Type: unsigned char, target_count
// Data           :     this+0x6, Member, Type: unsigned char, fire_count
// Data           :     this+0x7, Member, Type: unsigned short, count
// Data           :   this+0x2A, Member, Type: struct TS_SC_SKILL::CancelType, cancel
// UserDefinedType:     TS_SC_SKILL::CancelType
// 
// Data           :   this+0x2A, Member, Type: struct TS_SC_SKILL::CompleteType, complete
// UserDefinedType:     TS_SC_SKILL::CompleteType
// 
// Data           :   this+0x2A, Member, Type: struct TS_SC_SKILL::CastType, cast
// UserDefinedType:     TS_SC_SKILL::CastType
// 
// Data           :   this+0x2A, Member, Type: struct TS_SC_SKILL::FireType, fire
// UserDefinedType:     TS_SC_SKILL::FireType
// 
// UserDefinedType: TS_SC_SKILL::FireType
// Data           :   this+0x0, Member, Type: bool, bMultiple
// Data           :   this+0x1, Member, Type: float, range
// Data           :   this+0x5, Member, Type: unsigned char, target_count
// Data           :   this+0x6, Member, Type: unsigned char, fire_count
// Data           :   this+0x7, Member, Type: unsigned short, count
// UserDefinedType: TS_SC_SKILL::CastType
// Data           :   this+0x0, Member, Type: unsigned long, tm
// Data           :   this+0x4, Member, Type: unsigned short, nErrorCode
        public void WriteToPacket(PacketOut packet)
        {
            packet.WriteUInt16(skill_id);
            packet.WriteByte(skill_level);
            packet.WriteUInt32(caster);
            packet.WriteUInt32(target);
            packet.WriteFloat(x);
            packet.WriteFloat(y);
            packet.WriteFloat(z);
            packet.WriteByte(layer);
            packet.WriteByte(type);
            packet.WriteInt16(hp_cost);
            packet.WriteInt16(mp_cost);
            packet.WriteInt32(caster_hp);
            packet.WriteInt16(caster_mp);

        }

    }




}
